/*
 * 文件名称: DeviceFilterBean.java Copyright 2011-2015 Ximalaya All right reserved.
 */
package top.zxybird.common.web.filter;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

import javax.servlet.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import top.zxybird.common.util.CookieUtils;
import top.zxybird.common.util.RequestUtils;

/**
 * 负责解析cookie中的设备信息，并设置到request的Attribute中
 * 
 * @author Ted Wang
 */
public class DeviceFilterBean implements Filter {
  private static final Logger LOG = LoggerFactory.getLogger(DeviceFilterBean.class);
  public final static String DEVICE_COOKIE_KEY = "_device";
  public final static String DEVICE_MAC_KEY = "XUM";
  private String environmentId;

  public void setEnvironmentId(String environmentId) {
    this.environmentId = environmentId;
  }

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {

  }

  @Override
  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
      throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) req;
    String deviceCookieValue = null;
    String deviceCookieKey = getDeviceCookieKey(environmentId);
    Cookie[] cookies = request.getCookies();
    if (cookies != null) {
      for (Cookie cookie : cookies) {
        if (cookie.getName().equals(deviceCookieKey)) {
          deviceCookieValue = cookie.getValue();
          break;
        }
      }
    }
    if (StringUtils.hasText(deviceCookieValue)) {
      try {
        deviceCookieValue = URLDecoder.decode(deviceCookieValue, "UTF-8");
      } catch (UnsupportedEncodingException neverHappen) {
        LOG.error("Unsupported charset UTF-8", neverHappen);
      }
      String[] values = deviceCookieValue.split(CookieUtils.SYMBOL_AND);
      if (values.length == 3) {
        request.setAttribute(RequestUtils.CLIENT_DEVICE, values[0]);
        request.setAttribute(RequestUtils.CLIENT_DEVICE_ID, values[1]);
        request.setAttribute(RequestUtils.CLIENT_VERSION, values[2]);
      } else {
        injectRequestURLParams(request);
      }
    } else {
      injectRequestURLParams(request);
    }
    request.setAttribute(RequestUtils.CLIENT_BUNDLE_ID, CookieUtils.parseImpl(cookies));
    request.setAttribute(RequestUtils.CLIENT_CHANNEL_ID, CookieUtils.parseChannel(cookies));
    chain.doFilter(req, res);
  }

  @Override
  public void destroy() {

  }

  private static String getDeviceCookieKey(String environmentId) {
    StringBuilder sb = new StringBuilder();
    sb.append(environmentId).append(CookieUtils.SYMBOL_AND).append(DEVICE_COOKIE_KEY);
    return sb.toString();
  }

  public static String PARAM_VERSION = "version";
  public static String PARAM_DEVICE_ID = "deviceId";
  public static String PARAM_DEVICE = "device";

  /**
   * 应该是某些老版本通用参数使用query string的形式发送
   */
  private static void injectRequestURLParams(HttpServletRequest request) {
    request.setAttribute(RequestUtils.CLIENT_DEVICE, request.getParameter(PARAM_DEVICE));
    request.setAttribute(RequestUtils.CLIENT_DEVICE_ID, request.getParameter(PARAM_DEVICE_ID));
    request.setAttribute(RequestUtils.CLIENT_VERSION, request.getParameter(PARAM_VERSION));
  }

  public static String getDeviceId(HttpServletRequest request) {
    return (String) request.getAttribute(RequestUtils.CLIENT_DEVICE_ID);
  }

  public static String getDeviceType(HttpServletRequest request) {
    return (String) request.getAttribute(RequestUtils.CLIENT_DEVICE);
  }

  public static String getClientVersion(HttpServletRequest request) {
    return (String) request.getAttribute(RequestUtils.CLIENT_VERSION);
  }
}
